#include "ai_image.h"
#include "esp_log.h"
#include "esp_http_client.h"
#include "mbedtls/base64.h"
#include "cJSON.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_crt_bundle.h"  // 添加证书捆绑包头文件

static const char *TAG = "AI_IMAGE";

// 千问API配置
#define QIANWEN_URL "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions"
#define API_KEY "sk-f954de51de78401684df0e895b15e567"

// AI响应回调函数
static ai_image_callback_t ai_callback = NULL;

// Base64编码函数
static char* base64_encode(const uint8_t* data, size_t input_length, size_t* output_length) {
    size_t b64_len = ((input_length + 2) / 3) * 4 + 4; // 增加4字节安全余量
    
    // 分配内存（包含终止符）
    unsigned char* b64_data = malloc(b64_len + 1);
    if (!b64_data) {
        ESP_LOGE(TAG, "Base64内存分配失败");
        return NULL;
    }

    // 执行Base64编码
    int ret = mbedtls_base64_encode(
        b64_data, b64_len, output_length,
        data, input_length
    );

    if (ret != 0) {
        ESP_LOGE(TAG, "Base64编码失败，错误码: %d", ret);
        free(b64_data);
        return NULL;
    }

    // 添加终止符
    b64_data[*output_length] = '\0';
    
    return (char*)b64_data;
}

// HTTP事件处理程序
static esp_err_t http_event_handler(esp_http_client_event_t *evt) {
    static char* response_buffer = NULL;
    static size_t response_len = 0;
    
    switch (evt->event_id) {
        case HTTP_EVENT_ON_DATA:
            ESP_LOGI(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
            if (!esp_http_client_is_chunked_response(evt->client)) {
                // 分配或扩展缓冲区
                if (response_buffer == NULL) {
                    response_buffer = malloc(evt->data_len + 1);
                    if (response_buffer) {
                        memcpy(response_buffer, evt->data, evt->data_len);
                        response_len = evt->data_len;
                        response_buffer[response_len] = '\0';
                    }
                } else {
                    char* new_buffer = realloc(response_buffer, response_len + evt->data_len + 1);
                    if (new_buffer) {
                        response_buffer = new_buffer;
                        memcpy(response_buffer + response_len, evt->data, evt->data_len);
                        response_len += evt->data_len;
                        response_buffer[response_len] = '\0';
                    }
                }
            }
            break;
            
        case HTTP_EVENT_ON_FINISH:
            ESP_LOGI(TAG, "HTTP_EVENT_ON_FINISH");
            if (response_buffer != NULL && response_len > 0) {
                // 解析API响应
                cJSON *root = cJSON_Parse(response_buffer);
                if (root != NULL) {
                    cJSON *choices = cJSON_GetObjectItem(root, "choices");
                    if (choices != NULL && cJSON_IsArray(choices)) {
                        cJSON *first_choice = cJSON_GetArrayItem(choices, 0);
                        if (first_choice != NULL) {
                            cJSON *message = cJSON_GetObjectItem(first_choice, "message");
                            if (message != NULL) {
                                cJSON *content = cJSON_GetObjectItem(message, "content");
                                if (content != NULL && cJSON_IsString(content)) {
                                    ESP_LOGI(TAG, "AI图像分析结果: %s", content->valuestring);
                                    // 调用回调函数传递AI响应
                                    if (ai_callback != NULL) {
                                        ai_callback(content->valuestring);
                                    }
                                }
                            }
                        }
                    }
                    cJSON_Delete(root);
                }
                
                free(response_buffer);
                response_buffer = NULL;
                response_len = 0;
            }
            break;
            
        case HTTP_EVENT_ERROR:
            ESP_LOGI(TAG, "HTTP_EVENT_ERROR");
            if (response_buffer != NULL) {
                free(response_buffer);
                response_buffer = NULL;
                response_len = 0;
            }
            if (ai_callback != NULL) {
                ai_callback("AI图像分析请求失败");
            }
            break;
            
        default:
            break;
    }
    return ESP_OK;
}

// 发送图像到AI进行分析
void send_image_to_ai(camera_fb_t *fb) {
    if (fb == NULL) {
        ESP_LOGE(TAG, "无效的帧缓冲区");
        if (ai_callback != NULL) {
            ai_callback("获取图像失败");
        }
        return;
    }
    
    // 将图像转换为Base64
    size_t b64_len;
    char* b64_data = base64_encode(fb->buf, fb->len, &b64_len);
    if (b64_data == NULL) {
        ESP_LOGE(TAG, "Base64编码失败");
        if (ai_callback != NULL) {
            ai_callback("图像编码失败");
        }
        return;
    }
    
    // 构建请求JSON
    cJSON *root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "model", "qwen-vl-max"); // 使用千问VL模型
    
    // 构建消息数组
    cJSON *messages = cJSON_CreateArray();
    cJSON *msg = cJSON_CreateObject();
    cJSON_AddStringToObject(msg, "role", "user");
    
    // 创建content数组，用于包含文本和图像数据
    cJSON *content_array = cJSON_CreateArray();
    
    // 创建文本部分
    cJSON *text_item = cJSON_CreateObject();
    cJSON_AddStringToObject(text_item, "type", "text");
    cJSON_AddStringToObject(text_item, "text", "请分析以下图片并详细描述其内容");
    cJSON_AddItemToArray(content_array, text_item);
    
    // 创建图像部分
    cJSON *image_item = cJSON_CreateObject();
    cJSON_AddStringToObject(image_item, "type", "image_url");
    cJSON *image_url_obj = cJSON_CreateObject();
    
    // 构建Data URL: data:image/jpeg;base64,<base64_data>
    size_t data_url_len = strlen("data:image/jpeg;base64,") + strlen(b64_data) + 1;
    char *data_url = malloc(data_url_len);
    if (data_url == NULL) {
        ESP_LOGE(TAG, "Data URL内存分配失败");
        // 清理资源
        cJSON_Delete(root);
        free(b64_data);
        if (ai_callback != NULL) {
            ai_callback("内存分配失败");
        }
        return;
    }
    strcpy(data_url, "data:image/jpeg;base64,");
    strcat(data_url, b64_data);
    
    cJSON_AddStringToObject(image_url_obj, "url", data_url);
    cJSON_AddItemToObject(image_item, "image_url", image_url_obj);
    cJSON_AddItemToArray(content_array, image_item);
    
    // 将content数组添加到消息
    cJSON_AddItemToObject(msg, "content", content_array);
    
    // 将消息添加到消息数组
    cJSON_AddItemToArray(messages, msg);
    cJSON_AddItemToObject(root, "messages", messages);
    
    // 释放Data URL内存，因为cJSON已复制字符串
    free(data_url);
    
    char *request_body = cJSON_PrintUnformatted(root);
    ESP_LOGI(TAG, "请求体大小: %d", strlen(request_body));
    
    // 配置HTTP客户端
    esp_http_client_config_t config = {
        .url = QIANWEN_URL,
        .event_handler = http_event_handler,
        .method = HTTP_METHOD_POST,
        .timeout_ms = 15000,
        // 修改证书验证配置，与参考代码保持一致
        .crt_bundle_attach = esp_crt_bundle_attach,  // 使用证书捆绑包
        .cert_pem = NULL,  // 使用证书捆绑包时，cert_pem设为NULL
    };
    
    esp_http_client_handle_t client = esp_http_client_init(&config);
    
    // 设置请求头
    esp_http_client_set_header(client, "Content-Type", "application/json");
    char auth_header[128];
    snprintf(auth_header, sizeof(auth_header), "Bearer %s", API_KEY);
    esp_http_client_set_header(client, "Authorization", auth_header);
    
    // 设置请求体
    esp_http_client_set_post_field(client, request_body, strlen(request_body));
    
    // 发送请求
    esp_err_t err = esp_http_client_perform(client);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "HTTP请求失败: %s", esp_err_to_name(err));
        
        // 简化错误处理，使用esp_err_to_name获取错误描述
        char error_msg[128];
        snprintf(error_msg, sizeof(error_msg), "HTTP请求失败: %s", esp_err_to_name(err));
        
        if (ai_callback != NULL) {
            ai_callback(error_msg);
        }
    }
    
    // 清理资源
    esp_http_client_cleanup(client);
    cJSON_Delete(root);
    free(request_body);
    free(b64_data);
}

// 设置AI响应回调函数
void set_ai_image_callback(ai_image_callback_t callback) {
    ai_callback = callback;
}

// 初始化AI图像处理功能
void ai_image_init(void) {
    ESP_LOGI(TAG, "AI图像处理功能初始化完成");
}